<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<title>Irrlicht 3D Engine: Tutorial 23: SMeshBufferHandling</title>

<link href="tabs.css" rel="stylesheet" type="text/css"/>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
<link href="navtree.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="resize.js"></script>
<script type="text/javascript" src="navtree.js"></script>
<script type="text/javascript">
  $(document).ready(initResizable);
</script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/search.js"></script>
<script type="text/javascript">
  $(document).ready(function() { searchBox.OnSelectItem(0); });
</script>

</head>
<body>
<div id="top"><!-- do not remove this div! -->


<div id="titlearea">
<table cellspacing="0" cellpadding="0">
 <tbody>
 <tr style="height: 56px;">
  
  <td id="projectlogo"><img alt="Logo" src="irrlichtlogo.png"/></td>
  
  
  <td style="padding-left: 0.5em;">
   <div id="projectname">Irrlicht 3D Engine
   
   </div>
   
  </td>
  
  
  
   
   <td>        <div id="MSearchBox" class="MSearchBoxInactive">
        <span class="left">
          <img id="MSearchSelect" src="search/mag_sel.png"
               onmouseover="return searchBox.OnSearchSelectShow()"
               onmouseout="return searchBox.OnSearchSelectHide()"
               alt=""/>
          <input type="text" id="MSearchField" value="Search" accesskey="S"
               onfocus="searchBox.OnSearchFieldFocus(true)" 
               onblur="searchBox.OnSearchFieldFocus(false)" 
               onkeyup="searchBox.OnSearchFieldChange(event)"/>
          </span><span class="right">
            <a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.png" alt=""/></a>
          </span>
        </div>
</td>
   
  
 </tr>
 </tbody>
</table>
</div>

<!-- Generated by Doxygen 1.7.5.1 -->
<script type="text/javascript">
var searchBox = new SearchBox("searchBox", "search",false,'Search');
</script>
<script type="text/javascript" src="dynsections.js"></script>
</div>
<div id="side-nav" class="ui-resizable side-nav-resizable">
  <div id="nav-tree">
    <div id="nav-tree-contents">
    </div>
  </div>
  <div id="splitbar" style="-moz-user-select:none;" 
       class="ui-resizable-handle">
  </div>
</div>
<script type="text/javascript">
  initNavTree('example023.html','');
</script>
<div id="doc-content">
<div class="header">
  <div class="headertitle">
<div class="title">Tutorial 23: SMeshBufferHandling </div>  </div>
</div>
<div class="contents">
<div class="textblock"><div class="image">
<img src="023shot.jpg" alt="023shot.jpg"/>
</div>
 <p>A tutorial by geoff.</p>
<p>In this tutorial we'll learn how to create custom meshes and deal with them with Irrlicht. We'll create an interesting heightmap with some lighting effects. With keys 1,2,3 you can choose a different mesh layout, which is put into the mesh buffers as desired. All positions, normals, etc. are updated accordingly.</p>
<p>Ok, let's start with the headers (I think there's nothing to say about it) </p>
<div class="fragment"><pre class="fragment"><span class="preprocessor">#include &lt;<a class="code" href="irrlicht_8h.html" title="Main header file of the irrlicht, the only file needed to include.">irrlicht.h</a>&gt;</span>
<span class="preprocessor">#include &quot;<a class="code" href="driver_choice_8h.html">driverChoice.h</a>&quot;</span>

<span class="preprocessor">#ifdef _MSC_VER</span>
<span class="preprocessor"></span><span class="preprocessor">#pragma comment(lib, &quot;Irrlicht.lib&quot;)</span>
<span class="preprocessor"></span><span class="preprocessor">#endif</span>
<span class="preprocessor"></span>
<span class="comment">//Namespaces for the engine</span>
<span class="keyword">using namespace </span>irr;
<span class="keyword">using namespace </span>video;
<span class="keyword">using namespace </span>core;
<span class="keyword">using namespace </span>scene;
<span class="keyword">using namespace </span>io;
<span class="keyword">using namespace </span>gui;
</pre></div><p> This is the type of the functions which work out the colour. </p>
<div class="fragment"><pre class="fragment"><span class="keyword">typedef</span> SColor colour_func(<a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> x, <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> y, <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> z);
</pre></div><p> Here comes a set of functions which can be used for coloring the nodes while creating the mesh. </p>
<div class="fragment"><pre class="fragment"><span class="comment">// Greyscale, based on the height.</span>
SColor grey(<a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a>, <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a>, <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> z)
{
    <a class="code" href="namespaceirr.html#a0416a53257075833e7002efd0a18e804" title="32 bit unsigned variable.">u32</a> n = (<a class="code" href="namespaceirr.html#a0416a53257075833e7002efd0a18e804" title="32 bit unsigned variable.">u32</a>)(255.f * z);
    <span class="keywordflow">return</span> SColor(255, n, n, n);
}

<span class="comment">// Interpolation between blue and white, with red added in one</span>
<span class="comment">// direction and green in the other.</span>
SColor yellow(<a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> x, <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> y, <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a>)
{
    <span class="keywordflow">return</span> SColor(255, 128 + (<a class="code" href="namespaceirr.html#a0416a53257075833e7002efd0a18e804" title="32 bit unsigned variable.">u32</a>)(127.f * x), 128 + (<a class="code" href="namespaceirr.html#a0416a53257075833e7002efd0a18e804" title="32 bit unsigned variable.">u32</a>)(127.f * y), 255);
}

<span class="comment">// Pure white.</span>
SColor white(<a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a>, <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a>, <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a>) { <span class="keywordflow">return</span> SColor(255, 255, 255, 255); }
</pre></div><p> The type of the functions which generate the heightmap. x and y range between -0.5 and 0.5, and s is the scale of the heightmap. </p>
<div class="fragment"><pre class="fragment"><span class="keyword">typedef</span> <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> generate_func(<a class="code" href="namespaceirr.html#a43ace0af066371ac0862bac3f7314220" title="16 bit signed variable.">s16</a> x, <a class="code" href="namespaceirr.html#a43ace0af066371ac0862bac3f7314220" title="16 bit signed variable.">s16</a> y, <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> s);

<span class="comment">// An interesting sample function :-)</span>
<a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> eggbox(<a class="code" href="namespaceirr.html#a43ace0af066371ac0862bac3f7314220" title="16 bit signed variable.">s16</a> x, <a class="code" href="namespaceirr.html#a43ace0af066371ac0862bac3f7314220" title="16 bit signed variable.">s16</a> y, <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> s)
{
    <span class="keyword">const</span> <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> r = 4.f*sqrtf((<a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a>)(x*x + y*y))/s;
    <span class="keyword">const</span> <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> z = expf(-r * 2) * (cosf(0.2f * x) + cosf(0.2f * y));
    <span class="keywordflow">return</span> 0.25f+0.25f*z;
}

<span class="comment">// A rather dumb sine function :-/</span>
<a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> moresine(<a class="code" href="namespaceirr.html#a43ace0af066371ac0862bac3f7314220" title="16 bit signed variable.">s16</a> x, <a class="code" href="namespaceirr.html#a43ace0af066371ac0862bac3f7314220" title="16 bit signed variable.">s16</a> y, <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> s)
{
    <span class="keyword">const</span> <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> xx=0.3f*(<a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a>)x/s;
    <span class="keyword">const</span> <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> yy=12*y/s;
    <span class="keyword">const</span> <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> z = sinf(xx*xx+yy)*sinf(xx+yy*yy);
    <span class="keywordflow">return</span> 0.25f + 0.25f * z;
}

<span class="comment">// A simple function</span>
<a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> justexp(<a class="code" href="namespaceirr.html#a43ace0af066371ac0862bac3f7314220" title="16 bit signed variable.">s16</a> x, <a class="code" href="namespaceirr.html#a43ace0af066371ac0862bac3f7314220" title="16 bit signed variable.">s16</a> y, <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> s)
{
    <span class="keyword">const</span> <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> xx=6*x/s;
    <span class="keyword">const</span> <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> yy=6*y/s;
    <span class="keyword">const</span> <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> z = (xx*xx+yy*yy);
    <span class="keywordflow">return</span> 0.3f*z*cosf(xx*yy);
}
</pre></div><p> A simple class for representing heightmaps. Most of this should be obvious. </p>
<div class="fragment"><pre class="fragment"><span class="keyword">class </span>HeightMap
{
<span class="keyword">private</span>:
    <span class="keyword">const</span> <a class="code" href="namespaceirr.html#ae9f8ec82692ad3b83c21f555bfa70bcc" title="16 bit unsigned variable.">u16</a> Width;
    <span class="keyword">const</span> <a class="code" href="namespaceirr.html#ae9f8ec82692ad3b83c21f555bfa70bcc" title="16 bit unsigned variable.">u16</a> Height;
    <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> s;
    core::array&lt;f32&gt; data;
<span class="keyword">public</span>:
    HeightMap(<a class="code" href="namespaceirr.html#ae9f8ec82692ad3b83c21f555bfa70bcc" title="16 bit unsigned variable.">u16</a> _w, <a class="code" href="namespaceirr.html#ae9f8ec82692ad3b83c21f555bfa70bcc" title="16 bit unsigned variable.">u16</a> _h) : Width(_w), Height(_h), s(0.f), data(0)
    {
        s = sqrtf((<a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a>)(Width * Width + Height * Height));
        data.set_used(Width * Height);
    }

    <span class="comment">// Fill the heightmap with values generated from f.</span>
    <span class="keywordtype">void</span> generate(generate_func f)
    {
        <a class="code" href="namespaceirr.html#a0416a53257075833e7002efd0a18e804" title="32 bit unsigned variable.">u32</a> i=0;
        <span class="keywordflow">for</span>(<a class="code" href="namespaceirr.html#ae9f8ec82692ad3b83c21f555bfa70bcc" title="16 bit unsigned variable.">u16</a> y = 0; y &lt; Height; ++y)
            <span class="keywordflow">for</span>(<a class="code" href="namespaceirr.html#ae9f8ec82692ad3b83c21f555bfa70bcc" title="16 bit unsigned variable.">u16</a> x = 0; x &lt; Width; ++x)
                <span class="keyword">set</span>(i++, calc(f, x, y));
    }

    <a class="code" href="namespaceirr.html#ae9f8ec82692ad3b83c21f555bfa70bcc" title="16 bit unsigned variable.">u16</a> height()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> Height; }
    <a class="code" href="namespaceirr.html#ae9f8ec82692ad3b83c21f555bfa70bcc" title="16 bit unsigned variable.">u16</a> width()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> Width; }

    <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> calc(generate_func f, <a class="code" href="namespaceirr.html#ae9f8ec82692ad3b83c21f555bfa70bcc" title="16 bit unsigned variable.">u16</a> x, <a class="code" href="namespaceirr.html#ae9f8ec82692ad3b83c21f555bfa70bcc" title="16 bit unsigned variable.">u16</a> y)<span class="keyword"> const</span>
<span class="keyword">    </span>{
        <span class="keyword">const</span> <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> xx = (<a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a>)x - Width*0.5f;
        <span class="keyword">const</span> <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> yy = (<a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a>)y - Height*0.5f;
        <span class="keywordflow">return</span> f((<a class="code" href="namespaceirr.html#ae9f8ec82692ad3b83c21f555bfa70bcc" title="16 bit unsigned variable.">u16</a>)xx, (<a class="code" href="namespaceirr.html#ae9f8ec82692ad3b83c21f555bfa70bcc" title="16 bit unsigned variable.">u16</a>)yy, s);
    }

    <span class="comment">// The height at (x, y) is at position y * Width + x.</span>

    <span class="keywordtype">void</span> <span class="keyword">set</span>(<a class="code" href="namespaceirr.html#ae9f8ec82692ad3b83c21f555bfa70bcc" title="16 bit unsigned variable.">u16</a> x, <a class="code" href="namespaceirr.html#ae9f8ec82692ad3b83c21f555bfa70bcc" title="16 bit unsigned variable.">u16</a> y, <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> z) { data[y * Width + x] = z; }
    <span class="keywordtype">void</span> <span class="keyword">set</span>(<a class="code" href="namespaceirr.html#a0416a53257075833e7002efd0a18e804" title="32 bit unsigned variable.">u32</a> i, <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> z) { data[i] = z; }
    <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> <span class="keyword">get</span>(<a class="code" href="namespaceirr.html#ae9f8ec82692ad3b83c21f555bfa70bcc" title="16 bit unsigned variable.">u16</a> x, <a class="code" href="namespaceirr.html#ae9f8ec82692ad3b83c21f555bfa70bcc" title="16 bit unsigned variable.">u16</a> y) <span class="keyword">const</span> { <span class="keywordflow">return</span> data[y * Width + x]; }
</pre></div><p> The only difficult part. This considers the normal at (x, y) to be the cross product of the vectors between the adjacent points in the horizontal and vertical directions.</p>
<p>s is a scaling factor, which is necessary if the height units are different from the coordinate units; for example, if your map has heights in metres and the coordinates are in units of a kilometer. </p>
<div class="fragment"><pre class="fragment">    <a class="code" href="namespaceirr_1_1core.html#a06f169d08b5c429f5575acb7edbad811" title="Typedef for a f32 3d vector.">vector3df</a> getnormal(<a class="code" href="namespaceirr.html#ae9f8ec82692ad3b83c21f555bfa70bcc" title="16 bit unsigned variable.">u16</a> x, <a class="code" href="namespaceirr.html#ae9f8ec82692ad3b83c21f555bfa70bcc" title="16 bit unsigned variable.">u16</a> y, <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> s)<span class="keyword"> const</span>
<span class="keyword">    </span>{
        <span class="keyword">const</span> <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> zc = <span class="keyword">get</span>(x, y);
        <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> zl, zr, zu, zd;

        <span class="keywordflow">if</span> (x == 0)
        {
            zr = <span class="keyword">get</span>(x + 1, y);
            zl = zc + zc - zr;
        }
        <span class="keywordflow">else</span> <span class="keywordflow">if</span> (x == Width - 1)
        {
            zl = <span class="keyword">get</span>(x - 1, y);
            zr = zc + zc - zl;
        }
        <span class="keywordflow">else</span>
        {
            zr = <span class="keyword">get</span>(x + 1, y);
            zl = <span class="keyword">get</span>(x - 1, y);
        }

        <span class="keywordflow">if</span> (y == 0)
        {
            zd = <span class="keyword">get</span>(x, y + 1);
            zu = zc + zc - zd;
        }
        <span class="keywordflow">else</span> <span class="keywordflow">if</span> (y == Height - 1)
        {
            zu = <span class="keyword">get</span>(x, y - 1);
            zd = zc + zc - zu;
        }
        <span class="keywordflow">else</span>
        {
            zd = <span class="keyword">get</span>(x, y + 1);
            zu = <span class="keyword">get</span>(x, y - 1);
        }

        <span class="keywordflow">return</span> <a class="code" href="namespaceirr_1_1core.html#a06f169d08b5c429f5575acb7edbad811" title="Typedef for a f32 3d vector.">vector3df</a>(s * 2 * (zl - zr), 4, s * 2 * (zd - zu)).normalize();
    }
};
</pre></div><p> A class which generates a mesh from a heightmap. </p>
<div class="fragment"><pre class="fragment"><span class="keyword">class </span>TMesh
{
<span class="keyword">private</span>:
    <a class="code" href="namespaceirr.html#ae9f8ec82692ad3b83c21f555bfa70bcc" title="16 bit unsigned variable.">u16</a> Width;
    <a class="code" href="namespaceirr.html#ae9f8ec82692ad3b83c21f555bfa70bcc" title="16 bit unsigned variable.">u16</a> Height;
    <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> Scale;
<span class="keyword">public</span>:
    SMesh* Mesh;

    TMesh() : Mesh(0), Width(0), Height(0), Scale(1.f)
    {
        Mesh = <span class="keyword">new</span> SMesh();
    }

    ~TMesh()
    {
        Mesh-&gt;drop();
    }

    <span class="comment">// Unless the heightmap is small, it won&#39;t all fit into a single</span>
    <span class="comment">// SMeshBuffer. This function chops it into pieces and generates a</span>
    <span class="comment">// buffer from each one.</span>

    <span class="keywordtype">void</span> init(<span class="keyword">const</span> HeightMap &amp;hm, <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> scale, colour_func cf, IVideoDriver *driver)
    {
        Scale = scale;

        <span class="keyword">const</span> <a class="code" href="namespaceirr.html#a0416a53257075833e7002efd0a18e804" title="32 bit unsigned variable.">u32</a> mp = driver -&gt; getMaximalPrimitiveCount();
        Width = hm.width();
        Height = hm.height();
        
        <span class="keyword">const</span> <a class="code" href="namespaceirr.html#a0416a53257075833e7002efd0a18e804" title="32 bit unsigned variable.">u32</a> sw = mp / (6 * Height); <span class="comment">// the width of each piece</span>

        <a class="code" href="namespaceirr.html#a0416a53257075833e7002efd0a18e804" title="32 bit unsigned variable.">u32</a> i=0;
        <span class="keywordflow">for</span>(<a class="code" href="namespaceirr.html#a0416a53257075833e7002efd0a18e804" title="32 bit unsigned variable.">u32</a> y0 = 0; y0 &lt; Height; y0 += sw)
        {
            <a class="code" href="namespaceirr.html#ae9f8ec82692ad3b83c21f555bfa70bcc" title="16 bit unsigned variable.">u16</a> y1 = y0 + sw;
            <span class="keywordflow">if</span> (y1 &gt;= Height)
                y1 = Height - 1; <span class="comment">// the last one might be narrower</span>
            addstrip(hm, cf, y0, y1, i);
            ++i;
        }
        <span class="keywordflow">if</span> (i&lt;Mesh-&gt;getMeshBufferCount())
        {
            <span class="comment">// clear the rest</span>
            <span class="keywordflow">for</span> (<a class="code" href="namespaceirr.html#a0416a53257075833e7002efd0a18e804" title="32 bit unsigned variable.">u32</a> j=i; j&lt;Mesh-&gt;getMeshBufferCount(); ++j)
            {
                Mesh-&gt;getMeshBuffer(j)-&gt;drop();
            }
            Mesh-&gt;MeshBuffers.erase(i,Mesh-&gt;getMeshBufferCount()-i);
        }
        <span class="comment">// set dirty flag to make sure that hardware copies of this</span>
        <span class="comment">// buffer are also updated, see IMesh::setHardwareMappingHint</span>
        Mesh-&gt;setDirty();
        Mesh-&gt;recalculateBoundingBox();
    }

    <span class="comment">// Generate a SMeshBuffer which represents all the vertices and</span>
    <span class="comment">// indices for values of y between y0 and y1, and add it to the</span>
    <span class="comment">// mesh.</span>

    <span class="keywordtype">void</span> addstrip(<span class="keyword">const</span> HeightMap &amp;hm, colour_func cf, <a class="code" href="namespaceirr.html#ae9f8ec82692ad3b83c21f555bfa70bcc" title="16 bit unsigned variable.">u16</a> y0, <a class="code" href="namespaceirr.html#ae9f8ec82692ad3b83c21f555bfa70bcc" title="16 bit unsigned variable.">u16</a> y1, <a class="code" href="namespaceirr.html#a0416a53257075833e7002efd0a18e804" title="32 bit unsigned variable.">u32</a> bufNum)
    {
        <a class="code" href="namespaceirr_1_1scene.html#a76de145884afd2965d09c28d6bf89616" title="Standard meshbuffer.">SMeshBuffer</a> *buf = 0;
        <span class="keywordflow">if</span> (bufNum&lt;Mesh-&gt;getMeshBufferCount())
        {
            buf = (<a class="code" href="namespaceirr_1_1scene.html#a76de145884afd2965d09c28d6bf89616" title="Standard meshbuffer.">SMeshBuffer</a>*)Mesh-&gt;getMeshBuffer(bufNum);
        }
        <span class="keywordflow">else</span>
        {
            <span class="comment">// create new buffer</span>
            buf = <span class="keyword">new</span> <a class="code" href="namespaceirr_1_1scene.html#a76de145884afd2965d09c28d6bf89616" title="Standard meshbuffer.">SMeshBuffer</a>();
            Mesh-&gt;addMeshBuffer(buf);
            <span class="comment">// to simplify things we drop here but continue using buf</span>
            buf-&gt;drop();
        }
        buf-&gt;Vertices.set_used((1 + y1 - y0) * Width);

        <a class="code" href="namespaceirr.html#a0416a53257075833e7002efd0a18e804" title="32 bit unsigned variable.">u32</a> i=0;
        <span class="keywordflow">for</span> (<a class="code" href="namespaceirr.html#ae9f8ec82692ad3b83c21f555bfa70bcc" title="16 bit unsigned variable.">u16</a> y = y0; y &lt;= y1; ++y)
        {
            <span class="keywordflow">for</span> (<a class="code" href="namespaceirr.html#ae9f8ec82692ad3b83c21f555bfa70bcc" title="16 bit unsigned variable.">u16</a> x = 0; x &lt; Width; ++x)
            {
                <span class="keyword">const</span> <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> z = hm.get(x, y);
                <span class="keyword">const</span> <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> xx = (<a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a>)x/(<a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a>)Width;
                <span class="keyword">const</span> <a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a> yy = (<a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a>)y/(<a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a>)Height;

                S3DVertex&amp; v = buf-&gt;Vertices[i++];
                v.Pos.set(x, Scale * z, y);
                v.Normal.set(hm.getnormal(x, y, Scale));
                v.Color=cf(xx, yy, z);
                v.TCoords.set(xx, yy);
            }
        }

        buf-&gt;Indices.set_used(6 * (Width - 1) * (y1 - y0));
        i=0;
        <span class="keywordflow">for</span>(<a class="code" href="namespaceirr.html#ae9f8ec82692ad3b83c21f555bfa70bcc" title="16 bit unsigned variable.">u16</a> y = y0; y &lt; y1; ++y)
        {
            <span class="keywordflow">for</span>(<a class="code" href="namespaceirr.html#ae9f8ec82692ad3b83c21f555bfa70bcc" title="16 bit unsigned variable.">u16</a> x = 0; x &lt; Width - 1; ++x)
            {
                <span class="keyword">const</span> <a class="code" href="namespaceirr.html#ae9f8ec82692ad3b83c21f555bfa70bcc" title="16 bit unsigned variable.">u16</a> n = (y-y0) * Width + x;
                buf-&gt;Indices[i]=n;
                buf-&gt;Indices[++i]=n + Width;
                buf-&gt;Indices[++i]=n + Width + 1;
                buf-&gt;Indices[++i]=n + Width + 1;
                buf-&gt;Indices[++i]=n + 1;
                buf-&gt;Indices[++i]=n;
                ++i;
            }
        }

        buf-&gt;recalculateBoundingBox();
    }
};
</pre></div><p>Our event receiver implementation, taken from tutorial 4. </p>
<div class="fragment"><pre class="fragment"><span class="keyword">class </span>MyEventReceiver : <span class="keyword">public</span> IEventReceiver
{
<span class="keyword">public</span>:
    <span class="comment">// This is the one method that we have to implement</span>
    <span class="keyword">virtual</span> <span class="keywordtype">bool</span> OnEvent(<span class="keyword">const</span> SEvent&amp; event)
    {
        <span class="comment">// Remember whether each key is down or up</span>
        <span class="keywordflow">if</span> (event.EventType == <a class="code" href="namespaceirr.html#ac9eed96e06e85ce3c86fcbbbe9e48a0ca6f90390f3147a1693e5e2e3422d6ca09" title="A key input event.">irr::EET_KEY_INPUT_EVENT</a>)
            KeyIsDown[<span class="keyword">event</span>.KeyInput.Key] = <span class="keyword">event</span>.KeyInput.PressedDown;

        <span class="keywordflow">return</span> <span class="keyword">false</span>;
    }

    <span class="comment">// This is used to check whether a key is being held down</span>
    <span class="keyword">virtual</span> <span class="keywordtype">bool</span> IsKeyDown(<a class="code" href="namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3">EKEY_CODE</a> keyCode)<span class="keyword"> const</span>
<span class="keyword">    </span>{
        <span class="keywordflow">return</span> KeyIsDown[keyCode];
    }

    MyEventReceiver()
    {
        <span class="keywordflow">for</span> (<a class="code" href="namespaceirr.html#a0416a53257075833e7002efd0a18e804" title="32 bit unsigned variable.">u32</a> i=0; i&lt;<a class="code" href="namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3a205b48c0c4ed7489ab8980657343283e">KEY_KEY_CODES_COUNT</a>; ++i)
            KeyIsDown[i] = <span class="keyword">false</span>;
    }

<span class="keyword">private</span>:
    <span class="comment">// We use this array to store the current state of each key</span>
    <span class="keywordtype">bool</span> KeyIsDown[<a class="code" href="namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3a205b48c0c4ed7489ab8980657343283e">KEY_KEY_CODES_COUNT</a>];
};
</pre></div><p>Much of this is code taken from some of the examples. We merely set up a mesh from a heightmap, light it with a moving light, and allow the user to navigate around it. </p>
<div class="fragment"><pre class="fragment"><span class="keywordtype">int</span> main(<span class="keywordtype">int</span> argc, <span class="keywordtype">char</span>* argv[])
{
    <span class="comment">// ask user for driver</span>
    <a class="code" href="namespaceirr_1_1video.html#ae35a6de6d436c76107ad157fe42356d0" title="An enum for all types of drivers the Irrlicht Engine supports.">video::E_DRIVER_TYPE</a> driverType=driverChoiceConsole();
    <span class="keywordflow">if</span> (driverType==<a class="code" href="namespaceirr_1_1video.html#ae35a6de6d436c76107ad157fe42356d0ae685cada50f8c100403134d932d0414c" title="No driver, just for counting the elements.">video::EDT_COUNT</a>)
        <span class="keywordflow">return</span> 1;

    MyEventReceiver receiver;
    IrrlichtDevice* device = <a class="code" href="namespaceirr.html#abaf4d8719cc26b0d30813abf85e47c76" title="Creates an Irrlicht device. The Irrlicht device is the root object for using the engine.">createDevice</a>(driverType,
            <a class="code" href="namespaceirr_1_1core.html#ad2e562e3219072e2f7fc7c2bba0ef0cb" title="Typedef for an unsigned integer dimension.">core::dimension2du</a>(800, 600), 32, <span class="keyword">false</span>, <span class="keyword">false</span>, <span class="keyword">false</span>,
            &amp;receiver);

    <span class="keywordflow">if</span>(device == 0)
        <span class="keywordflow">return</span> 1;
 
    IVideoDriver *driver = device-&gt;getVideoDriver();
    ISceneManager *smgr = device-&gt;getSceneManager();
    device-&gt;setWindowCaption(L<span class="stringliteral">&quot;Irrlicht Example for SMesh usage.&quot;</span>);
</pre></div><p>Create the custom mesh and initialize with a heightmap </p>
<div class="fragment"><pre class="fragment">    TMesh mesh;
    HeightMap hm = HeightMap(255, 255);
    hm.generate(eggbox);
    mesh.init(hm, 50.f, grey, driver);

    <span class="comment">// Add the mesh to the scene graph</span>
    IMeshSceneNode* meshnode = smgr -&gt; addMeshSceneNode(mesh.Mesh);
    meshnode-&gt;setMaterialFlag(<a class="code" href="namespaceirr_1_1video.html#a8a3bc00ae8137535b9fbc5f40add70d3ae1d176d0ce05ccc5df9e43ce854393bb" title="Is backface culling enabled? Default: true.">video::EMF_BACK_FACE_CULLING</a>, <span class="keyword">false</span>);

    <span class="comment">// light is just for nice effects</span>
    ILightSceneNode *node = smgr-&gt;addLightSceneNode(0, <a class="code" href="namespaceirr_1_1core.html#a06f169d08b5c429f5575acb7edbad811" title="Typedef for a f32 3d vector.">vector3df</a>(0,100,0),
        SColorf(1.0f, 0.6f, 0.7f, 1.0f), 500.0f);
    <span class="keywordflow">if</span> (node)
    {
        node-&gt;getLightData().Attenuation.set(0.f, 1.f/500.f, 0.f);
        ISceneNodeAnimator* anim = smgr-&gt;createFlyCircleAnimator(<a class="code" href="namespaceirr_1_1core.html#a06f169d08b5c429f5575acb7edbad811" title="Typedef for a f32 3d vector.">vector3df</a>(0,150,0),250.0f);
        <span class="keywordflow">if</span> (anim)
        {
            node-&gt;addAnimator(anim);
            anim-&gt;drop();
        }
    }

    ICameraSceneNode* camera = smgr-&gt;addCameraSceneNodeFPS();
    <span class="keywordflow">if</span> (camera)
    {
        camera-&gt;setPosition(<a class="code" href="namespaceirr_1_1core.html#a06f169d08b5c429f5575acb7edbad811" title="Typedef for a f32 3d vector.">vector3df</a>(-20.f, 150.f, -20.f));
        camera-&gt;setTarget(<a class="code" href="namespaceirr_1_1core.html#a06f169d08b5c429f5575acb7edbad811" title="Typedef for a f32 3d vector.">vector3df</a>(200.f, -80.f, 150.f));
        camera-&gt;setFarValue(20000.0f);
    }
</pre></div><p>Just a usual render loop with event handling. The custom mesh is a usual part of the scene graph which gets rendered by drawAll. </p>
<div class="fragment"><pre class="fragment">    <span class="keywordflow">while</span>(device-&gt;run())
    {
        <span class="keywordflow">if</span>(!device-&gt;isWindowActive())
        {
            device-&gt;sleep(100);
            <span class="keywordflow">continue</span>;
        }

        <span class="keywordflow">if</span>(receiver.IsKeyDown(<a class="code" href="namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3ae559e3169016a3180c45c2828f391af2">irr::KEY_KEY_W</a>))
        {
            meshnode-&gt;setMaterialFlag(<a class="code" href="namespaceirr_1_1video.html#a8a3bc00ae8137535b9fbc5f40add70d3abc620823efed8d6bdbd46c8a0180893a" title="Draw as wireframe or filled triangles? Default: false.">video::EMF_WIREFRAME</a>, !meshnode-&gt;getMaterial(0).Wireframe);
        }
        <span class="keywordflow">else</span> <span class="keywordflow">if</span>(receiver.IsKeyDown(<a class="code" href="namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3a61ec605d669b598d2e7106981a326fde">irr::KEY_KEY_1</a>))
        {
            hm.generate(eggbox);
            mesh.init(hm, 50.f, grey, driver);
        }
        <span class="keywordflow">else</span> <span class="keywordflow">if</span>(receiver.IsKeyDown(<a class="code" href="namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3aa7574bf313b5c29547f01c36f0a4a4f8">irr::KEY_KEY_2</a>))
        {
            hm.generate(moresine);
            mesh.init(hm, 50.f, yellow, driver);
        }
        <span class="keywordflow">else</span> <span class="keywordflow">if</span>(receiver.IsKeyDown(<a class="code" href="namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3a577dcff3b86e6dd45f70d8c691dd3c91">irr::KEY_KEY_3</a>))
        {
            hm.generate(justexp);
            mesh.init(hm, 50.f, yellow, driver);
        }

        driver-&gt;beginScene(<span class="keyword">true</span>, <span class="keyword">true</span>, SColor(0xff000000));
        smgr-&gt;drawAll();
        driver-&gt;endScene();
    }

    device-&gt;drop();

    <span class="keywordflow">return</span> 0;
}
</pre></div><p>That's it! Just compile and play around with the program. </p>
</div></div>
</div>
  <div id="nav-path" class="navpath">
    <ul>
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
     onmouseover="return searchBox.OnSearchSelectShow()"
     onmouseout="return searchBox.OnSearchSelectHide()"
     onkeydown="return searchBox.OnSearchSelectKey(event)">
<a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(0)"><span class="SelectionMark">&#160;</span>All</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(1)"><span class="SelectionMark">&#160;</span>Classes</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(2)"><span class="SelectionMark">&#160;</span>Namespaces</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(3)"><span class="SelectionMark">&#160;</span>Files</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(4)"><span class="SelectionMark">&#160;</span>Functions</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(5)"><span class="SelectionMark">&#160;</span>Variables</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(6)"><span class="SelectionMark">&#160;</span>Typedefs</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(7)"><span class="SelectionMark">&#160;</span>Enumerations</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(8)"><span class="SelectionMark">&#160;</span>Enumerator</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(9)"><span class="SelectionMark">&#160;</span>Friends</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(10)"><span class="SelectionMark">&#160;</span>Defines</a></div>

<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0" 
        name="MSearchResults" id="MSearchResults">
</iframe>
</div>


    <li class="footer">
<a href="http://irrlicht.sourceforge.net" target="_blank">Irrlicht 
Engine</a> Documentation &copy; 2003-2012 by Nikolaus Gebhardt. Generated on Sat Jul 9 2016 18:18:27 for Irrlicht 3D Engine by
<a href="http://www.doxygen.org/index.html" target="_blank">Doxygen</a> 1.7.5.1 </li>
   </ul>
 </div>


</body>
</html>
